/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	GeometryElementInfo.cpp
*
*	Comments	-	See GeometryElementInfo.h
*
**************************************************************************************/
#include "../Include/GeometryElementInfo.h"

namespace Pulse
{
	SIZE_T GeometryElementInfo::GetVertexSize( EVertexElement::Type type )
	{
		switch( type )
		{
		case EVertexElement::POSITION:
			return sizeof( Vector3 );
		case EVertexElement::NORMAL:
			return sizeof( Vector3 );
		case EVertexElement::TEXTURE_DIFFUSE:
			return sizeof( Vector2 );
		};

		PSX_PushError( "Element type size not yet implemented." );

		return 0;
	}

	const CHAR * GeometryElementInfo::GetVertexName( EVertexElement::Type type )
	{
		switch( type )
		{
		case EVertexElement::POSITION:
			return PSX_String("Position");
		case EVertexElement::COLOR:
			return PSX_String("Color");
		case EVertexElement::NORMAL:
			return PSX_String("Normal");
		case EVertexElement::TEXTURE_DIFFUSE:
			return PSX_String("TextureDiffuse");
		};

		PSX_PushError( "Element type name not yet implemented." );

		return PSX_String("EVertexElementType no name.");
	}


	EVertexElement::Type GeometryElementInfo::GetVertexType( const CHAR *pName )
	{
		if ( PSX_StrCmp( pName, PSX_String("Position") ) == 0 )
			return EVertexElement::POSITION;
		else if ( PSX_StrCmp( pName, PSX_String("Color") ) == 0 )
			return EVertexElement::COLOR;
		else if ( PSX_StrCmp( pName, PSX_String("Normal") ) == 0 )
			return EVertexElement::NORMAL;
		else if ( PSX_StrCmp( pName, PSX_String("Tangent") ) == 0 )
			return EVertexElement::TANGENT;
		else if ( PSX_StrCmp( pName, PSX_String("TextureDiffuse") ) == 0 )
			return EVertexElement::TEXTURE_DIFFUSE;
		else
		{
			PSX_PushError( "Vertex type %s not yet supported.", pName );
			return EVertexElement::UNKNOWN;
		}

	}

	EVertexElement::Type GeometryElementInfo::GetVertexType( const String *pName )
	{
		return GetVertexType( pName->GetBuffer() );
	}

	const CHAR * GeometryElementInfo::GetVertexSemanticName( EVertexElement::Type type )
	{
		switch( type )
		{
		case EVertexElement::POSITION:
			return PSX_String("POSITION");
		case EVertexElement::COLOR:
			return PSX_String("COLOR");
		case EVertexElement::NORMAL:
			return PSX_String("NORMAL");
		case EVertexElement::TEXTURE_DIFFUSE:
			return PSX_String("TEXCOORD_DIFFUSE");
		};

		PSX_PushError( "Element type name not yet implemented." );

		return PSX_String("EVertexElementType no name.");
	}

	EGraphicsFormat::Type GeometryElementInfo::GetVertexGraphicsFormat( EVertexElement::Type type )
	{
		switch( type )
		{
		case EVertexElement::POSITION:
		case EVertexElement::COLOR:
		case EVertexElement::NORMAL:
			return EGraphicsFormat::R32G32B32_FLOAT;
		case EVertexElement::TEXTURE_DIFFUSE:
			return EGraphicsFormat::R32G32_FLOAT;
		};

		PSX_PushError( "Element type not yet implemented." );

		return EGraphicsFormat::UNKNOWN;
	}

	EErrorCode::Type GeometryElementInfo::GetRequirementElement( XMLElementPtr pElem, GeometryElementRequirement *pRequirement )
	{
		if ( pElem.IsNull() || pRequirement == PSX_NULL )
			return EErrorCode::_ERROR;
		
		pRequirement->m_type = EVertexElement::UNKNOWN;

		String typeString = pElem->GetValue();

		EVertexElement::Type type = GetVertexType( typeString.GetBuffer() );

		if( type != EVertexElement::UNKNOWN )
			pRequirement->m_type = type;

		return EErrorCode::OKAY;
	}

}